package com.sample.springbatch.job.sample.config;

import com.sample.springbatch.job.exception.MySkipException;
import com.sample.springbatch.job.config.BaseConfig;
import com.sample.springbatch.job.sample.listener.RepayOrderStepListener;
import com.sample.springbatch.job.sample.processor.RepayOrderProcessor;
import com.sample.springbatch.job.sample.reader.RepayOrderFlatFileItemReader;
import com.sample.springbatch.job.sample.reader.RepayOrderJpaPagingItemReader;
import com.sample.springbatch.job.sample.reader.RepayOrderMultiResourceFlatFileItemReader;
import com.sample.springbatch.job.sample.reader.RepayOrderParamsFlatFileItemReader;
import com.sample.springbatch.job.sample.writer.*;
import com.sample.springbatch.model.RepayOrderInfo;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.item.file.FlatFileParseException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.SimpleAsyncTaskExecutor;

import java.util.Map;


/**
 * Created by zwg on 2017/7/14.
 */
@Configuration
public class RepayOrderConfig extends BaseConfig {



    @Autowired
    private RepayOrderStepListener repayOrderStepListener;


    @Autowired
    public RepayOrderFlatFileItemReader repayOrderFlatFileItemReader;




    /**
     * 获取job参数示例
     * @param times  直接获取参数值
     * @param params 获取全部参数
     * @return
     */
    @Bean(name="repayOrderFlatFileItemReaderOfParams")
    @StepScope
    public RepayOrderParamsFlatFileItemReader<RepayOrderInfo> repayOrderFlatFileItemReaderOfParams(@Value("#{jobParameters[times]}") String times,@Value("#{jobParameters}") Map params){
        System.out.println("repayOrderFlatFileItemReaderOfParams================times:"+times);
        System.out.println("repayOrderFlatFileItemReaderOfParams================times:"+params.keySet().toString());
        RepayOrderParamsFlatFileItemReader<RepayOrderInfo> reader = new RepayOrderParamsFlatFileItemReader<>();
        if(params!=null && params.containsKey("filePath")){
            reader.setFilePath(params.get("filePath").toString());
        }

        return reader;
    }

    /**
     * 获取job参数示例
     * @param times  直接获取参数值
     * @param params 获取全部参数
     * @return
     */
    @Bean(name="repayOrderFlatFileItemWriterOfParams")
    @StepScope
    public RepayOrderParamsFlatFileItemWriter<RepayOrderInfo> repayOrderFlatFileItemWriterOfParams(@Value("#{jobParameters[times]}") String times,@Value("#{jobParameters}") Map params){
        System.out.println("repayOrderFlatFileItemWriterOfParams================times:"+times);
        System.out.println("repayOrderFlatFileItemWriterOfParams================times:"+params.keySet().toString());
        RepayOrderParamsFlatFileItemWriter<RepayOrderInfo> writer = new RepayOrderParamsFlatFileItemWriter<>();
        if(params!=null && params.containsKey("writerFilePath")){
            writer.setFilePath(params.get("writerFilePath").toString());
        }

        return writer;
    }

    @Autowired
    RepayOrderJpaPagingItemReader repayOrderJpaPagingItemReader;

    @Autowired
    RepayOrderMultiResourceFlatFileItemReader repayOrderMultiResourceFlatFileItemReader;
    @Bean
    public RepayOrderProcessor repayOrderProcessor() {
        return new RepayOrderProcessor();
    }

    @Autowired
    RepayOrderJdbcBatchItemWriter repayOrderJdbcBatchItemWriter;


    @Autowired
    RepayOrderJpaItemWriter repayOrderJpaItemWriter;

    @Autowired
    RepayOrderFlatFileItemWriter repayOrderFlatFileItemWriter;

    @Autowired
    RepayOrderMultiResourceFlatFileItemWriter repayOrderMultiResourceFlatFileItemWriter;
    @Autowired
    public RepayOrderClassifierCompositeItemWriter repayOrderClassifierCompositeItemWriter;

    public static final String REPAY_ORDER_JOB = "repayOrderJob";
    public static final String REPAY_ORDER_STEP = "repayOrderStep";


    @Bean(name = REPAY_ORDER_JOB)
    public Job repayOrderJob() {
    //public Job importUserJob(MyJobListener listener) {
        return jobBuilderFactory.get(REPAY_ORDER_JOB)
                .incrementer(new RunIdIncrementer())
                .listener(myJobListener) //增加对job的监听
                .flow(repayOrderStep())
                .end()
                .build();
    }

    @Bean(name=REPAY_ORDER_STEP)
    public Step repayOrderStep() {
        return stepBuilderFactory.get(REPAY_ORDER_STEP)
                .listener(repayOrderStepListener)  //添加对step的监听，可以实现多step的所有监听
                .<RepayOrderInfo, RepayOrderInfo> chunk(500)
                //跳过机制是针对每个执行线程设置，最大跳过数量为：skipLimit * throttleLimit
                .faultTolerant().skipLimit(9)
                .skip(FlatFileParseException.class)  //reader
                .skip(MySkipException.class) //processor 自定义异常
                .reader(repayOrderFlatFileItemReader)
                //.reader(repayOrderMultiResourceFlatFileItemReader)  //不支持多线程
                .processor(repayOrderProcessor())
                //.writer(repayOrderFlatFileItemWriter) //写文件
                //写多个文件  每个文件的记录条数依赖配置的记录数，还要看chunkSize每次读取的记录条数
                //.writer(repayOrderMultiResourceFlatFileItemWriter)
                //.writer(repayOrderJpaItemWriter) //写数据库
                .writer(repayOrderClassifierCompositeItemWriter)  //路由writer
                .stream(repayOrderFlatFileItemWriter)  //路由writer stream 必须添加些文件的writer
                //.stream(repayOrderMultiResourceFlatFileItemWriter)
                //开启异步多线程  需要注意readers 和writers是否允许多线程
                //.taskExecutor(new SimpleAsyncTaskExecutor())
                //.throttleLimit(5)
                .build();
    }

    /**
     * 获取作业参数的JOB
     * @param repayOrderStepOfParams
     * @return
     */
    @Bean(name = "repayOrderJobOfParams")
    public Job repayOrderJobOfParams(Step repayOrderStepOfParams) {
        return jobBuilderFactory.get("repayOrderJobOfParams")
                .incrementer(new RunIdIncrementer())
                //.listener(listener)
                .flow(repayOrderStepOfParams)
                .end()
                .build();
    }

    /**
     * 获取作业参数的step
     * @param repayOrderFlatFileItemReaderOfParams
     * @return
     */
    @Bean(name="repayOrderStepOfParams")
    public Step repayOrderStepOfParams(RepayOrderParamsFlatFileItemReader<RepayOrderInfo> repayOrderFlatFileItemReaderOfParams,
                                       RepayOrderParamsFlatFileItemWriter<RepayOrderInfo> repayOrderFlatFileItemWriterOfParam) {
        return stepBuilderFactory.get("repayOrderStepOfParams")
                .<RepayOrderInfo, RepayOrderInfo> chunk(100)
                .reader(repayOrderFlatFileItemReaderOfParams)
                .processor(repayOrderProcessor())
                .writer(repayOrderFlatFileItemWriterOfParam)
                //.taskExecutor(new SimpleAsyncTaskExecutor())
                //.throttleLimit(5)
                .build();
    }
}
